module render.renderer;

import scene.graph.node;
import scene.scene;

import derelict.opengl.gl;
import derelict.opengl.glu;
import derelict.sdl.sdl;

import tango.stdc.stringz;

class Renderer
{
	public:
		void render(Node n) {
			n.parent();
		}
		
		/**
		 * Resize and initialize the OpenGL window.
		 */
		void resizeGLScene(GLsizei width, GLsizei height)
		{
			if (height == 0)
			{
				height = 1;
			}
			// Reset The Current Viewport
			glViewport(0, 0, width, height);

			// Select The Projection Matrix
			glMatrixMode(GL_PROJECTION);

			// Reset The Projection Matrix
			glLoadIdentity();

			// Calculate The Aspect Ratio Of The Window
			gluPerspective(45.0f, cast(GLfloat) width / cast(GLfloat) height, 0.1f,
				100.0f);

			// Select The Modelview Matrix
			glMatrixMode(GL_MODELVIEW);

			// Reset The Modelview Matrix
			glLoadIdentity();
		}

		/**
		 * Initialize OpenGL.
		 */
		void initGL()
		{
			// Enables Smooth Shading
			glShadeModel(GL_SMOOTH);
			// Black Background
			glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			// Depth Buffer Setup
			glClearDepth(1.0f);
			// Enables Depth Testing
			glEnable(GL_DEPTH_TEST);
			// The Type Of Depth Test To Do
			glDepthFunc(GL_LEQUAL);
			// Really Nice Perspective Calculations
			glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
		}
		
		/**
		 * The drawing function. Now we only clear the color and depht buffers, so that
		 * the window stays black.
		 */
		void drawGLScene(Scene scene)
		{
			// Clear The Screen And The Depth Buffer
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			// Reset The Current Modelview Matrix
			glLoadIdentity();
		}
		
		/**
		 * Initializes and opens the SDL window.
		 */
		void createGLWindow(char[] title, int width, int height, int bits,
			bool fullScreen)
		{
			// Set the OpenGL attributes
			SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
			SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
			SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
			SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
			SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

			// Set the window title
			SDL_WM_SetCaption(toStringz(title), null);

			// Note the SDL_DOUBLEBUF flag is not required to enable double
			// buffering when setting an OpenGL video mode.
			// Double buffering is enabled or disabled using the
			// SDL_GL_DOUBLEBUFFER attribute. (See above.)
			int mode = SDL_OPENGL;
			if (fullScreen)
			{
				mode |= SDL_FULLSCREEN;
			}
			// Now open a SDL OpenGL window with the given parameters
			if (SDL_SetVideoMode(width, height, bits, mode) is null)
			{
				throw new Exception("Failed to open OpenGL window: " ~ getSDLError());
			}

			resizeGLScene(width, height);
		}
		
		char[] getSDLError()
		{
			return fromStringz(SDL_GetError());
		}

}
